import trackData from '../assets/data/track.json'
import EntityGenerator from '../utils/EntityGenerator';

import Draw from '../components/cesiums/draw/index'
import Measure from '../components/cesiums/measure/index'
import ConvertManager from '../components/cesiums/convert'

import ColorUtils from '../utils/ColorUtils';
import PolylineTrailLinkMaterial from '../components/cesiums/plugins/PolylineTrailLinkMaterial'
import FlowWall from '../components/cesiums/plugins/FlowWall'
import TimeLineManage from '../components/cesiums/plugins/TimeLineManage'
import RadarManage from '../components/cesiums/plugins/RadarManage'
import WallManage from '../components/cesiums/plugins/WallManage'
import * as cesium from 'cesium/Cesium'
import { Store } from './store'
import { vm, SEND } from './eventManage'
import * as turf from '@turf/turf'
const Cesium = cesium
class CesiumMap {
    constructor(objectList, callback) {
        // this.Cesium=window.cesium;
        this.viewer = window.viewer;

        this.draw=null;
        this.measure=null;
        this.convert=null;

        this.objectList = objectList;
        this.entityList = [];
        this.modelList = [];//模型数组
        this.trailEntityList = [];
        this.relations = [];//vue中要用
        this.callback = callback ? callback : null;
        this.relationLines = [];//所有的关系线
        this.popList = []
        this.handler = null;
        this.plugins = {};
        this.showRailWatch=false; //地理围栏监控,雷达
        this.showWallWatch=false;//动态墙体
        this.init();
        this.addPlugin();

        this.global = 0; // 用于调试时限制循环输出次数的
    }
    addPlugin() {
        this.plugins.flowWall = new FlowWall(this);
        this.plugins.timeLineManage = new TimeLineManage(this)
        this.plugins.radarManage=new RadarManage(this)
        this.plugins.wallManage=new WallManage(this)
    }
    init() {
        //this.flyTo()
        this.setTime()
        this.addModel()
        this.addEvents()
        this.convert=new ConvertManager(this);
        this.draw=new Draw(this);
        this.measure=new Measure(this);
        setTimeout(() => {
            this.startPlay()
        }, 5000)
        vm.$on(SEND.showTrail, data => {
            this.trailEntityList.forEach(el => {
                el.show = data.show
            })
        })
        vm.$on(SEND.showRailWatch, data => {
            this.showRailWatch=data.show
        })
        //动态墙体
        vm.$on(SEND.showWallWatch, data => {
            this.showWallWatch=data.show
        })
    }
    //添加点击事件
    addEvents() {
        this.handler && this.handler.destroy();
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
        this.handler.setInputAction(this.modelClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // this.handler.setInputAction(this.modelRightClick, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
     //笛卡尔转经纬度
  cartesian3ToDegrees = function (cartesian) {
    let cartographic = new Cesium.Cartographic.fromCartesian(cartesian);
    var longitude = Cesium.Math.toDegrees(cartographic.longitude);
    var latitude = Cesium.Math.toDegrees(cartographic.latitude);
    return {
      longitude: longitude,
      latitude: latitude,
      height: cartographic.height
    }
  }
    modelClick = event => {
        let pick = this.viewer.scene.pick(event.position);

        if (Cesium.defined(pick) && pick.id) {
            //选中entity
            vm.$emit(SEND.objectSelected, {object: pick.id.ref})
        }
        //获取地面经纬度+弹出对话框
        let cartesian = this.viewer.camera.pickEllipsoid(
            event.position,
            this.viewer.scene.globe.ellipsoid
        );

        //alert(JSON.stringify(this.cartesian3ToDegrees(cartesian)));
        
        let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(
            cartesian
        );

        if(this.showRailWatch){
            vm.$emit(SEND.showRadarAttr,{
                position:this.cartesian3ToDegrees(cartesian),
                pixel:event.position,
                show:true
            })
        }
        if(this.showWallWatch){
            
        }


        // console.log(cartesian, 77777)
        // this.plugins.radarManage.handleDrawEllipsoid(cartesian)
        //   if (cartesian) {
        //     //将笛卡尔坐标转换为地理坐标
        //     let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(
        //       cartesian
        //     );
        //     //将弧度转为度的十进制度表示
        //     let longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
        //     let latitudeString = Cesium.Math.toDegrees(cartographic.latitude);

        //     alert("(" + longitudeString + ", " + latitudeString + ")");
        //   }
    }
    modelRightClick=event=>{
        
        let pick = this.viewer.scene.pick(event.position);
         //获取地面经纬度+弹出对话框
         let cartesian = this.viewer.camera.pickEllipsoid(
            event.position,
            this.viewer.scene.globe.ellipsoid
        );
        if(this.showRailWatch){
            vm.$emit(SEND.showRadarAttr,{
                position:cartesian,
                pixel:event.position,
                show:true
            })
        }
        document.oncontextmenu = function () {
  return false
};
    }
    flyTo() {
        this.viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(118.13915733348445, 36.30586319468154, 10000),
            orientation: {
                heading: Cesium.Math.toRadians(0.0),
                pitch: Cesium.Math.toRadians(-25.0),
                roll: 0.0
            }
        });
    }
    startPlay() {
        this.viewer.shouldAnimate = true
        this.viewer.clock.shouldAnimate = true
        this.viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
        this.viewer.clock.multiplier = 1
    }
    setTime() {
        let viewer = this.viewer;
        let arr = [];
        for (let item of trackData) {
            for (let itemObj of item.data) {
                arr.push(itemObj.datetime)
            }
        }
        arr = arr.sort((a, b) => a - b)
        // console.log(arr,33333366666)
        let startTime = arr[0]
        let endTime = arr[arr.length - 1]
        this.viewer.clock.currentTime = Cesium.JulianDate.fromDate(new Date(startTime));
        this.viewer.clock.startTime = Cesium.JulianDate.fromDate(new Date(startTime));
        this.viewer.clock.stopTime = Cesium.JulianDate.fromDate(new Date(endTime));

        this.viewer.timeline.zoomTo(this.viewer.clock.startTime, this.viewer.clock.stopTime);
    }
    addModel() {
        let generator = new EntityGenerator(Cesium, this.viewer);
        for (let item of this.objectList) {
            let itemObj = generator.toEntity(item)
            this.startLoadSlider(itemObj);
        }
        // 添加关系
        for (let i in this.objectList) {
            let connections = generator.toConnections(this.objectList[i]);
            connections.forEach(connect => {

                let rt = this.relations.find(function (relation) {
                    return relation.type.id == connect.polyline.ref.relation.id;
                });

                if (rt) {
                    rt.data.push({
                        source: connect.polyline.ref.source,
                        target: connect.polyline.ref.target
                    });

                } else {
                    connect.polyline.material.color = Cesium.Color.fromCssColorString('#CD2417');
                    this.relations.push({
                        type: connect.polyline.ref.relation,
                        color: connect.polyline.material.color._value.toCssColorString(),
                        data: [
                            {
                                source: connect.polyline.ref.source,
                                target: connect.polyline.ref.target
                            }
                        ]
                    });

                }
                // connect.typeName='line'
                // this.viewer.entities.add(connect);
                let relationObj = connect.polyline.ref
                this.addRelationLine(relationObj)
            });
        }

        if (this.callback) {
            this.callback({ relations: this.relations })
        }
    }
    timeChange2(time) {
        var date = new Date(time);
        var time1 = date.getTime();
        return time1
    }
    getRelationPositions(time, connect) {
        let sourceObj = this.modelList.find(el => el.id == connect.source.id)
        let targetObj = this.modelList.find(el => el.id == connect.target.id)
        let sourcePos = sourceObj.entity.currentPos;
        let targetPos = targetObj.entity.currentPos;
        return [sourcePos, targetPos]
    }
    addRelationLine(connect) {
        let relationLine = this.viewer.entities.add({
            polyline: {
                positions: new Cesium.CallbackProperty((time, result) => {
                    return this.getRelationPositions(time, connect)
                }, false),
                width: 10,
                arcType: Cesium.ArcType.RHUMB,
                material: new Cesium.PolylineTrailLinkMaterialProperty(Cesium.Color.fromCssColorString('#CD2417'), 20000)
            },
        })
        relationLine.info = connect
        this.relationLines.push(relationLine)
    }
    //修改所有关系线颜色
    editRelationLins(cssColor) {
        for (let entity of this.relationLines) {
            entity.polyline.material.color = Cesium.Color.fromCssColorString(cssColor);
        }
    }
    startLoadSlider(item) {

        let obj = {
            id: item.id,
            info: item,
            position: null
        }
        this.popList.push({
            info: item,
            oid: item.id,
            show: false,
            pixel: {},
            name: item.name
        })
        Store.getPopList(this.popList);
        let modelMan = this.viewer.entities.add({
            id: item.id,
            position: new Cesium.CallbackProperty((time) => {
                return this.callbackPositionProperty(time, item, modelMan, obj)
            }, false),
            model: {
                uri: item.model.uri,
                scale: 35,
            },
            label: {
                text: item.name,
                font: "18px Helvetica",
                fillColor: Cesium.Color.SKYBLUE,
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 2,
                pixelOffset: new Cesium.Cartesian2(105, -10),
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            },
        })
        modelMan.originalData = item;
        modelMan.ref = item;
        modelMan.type = 'model'
        obj.entity = modelMan;
        this.modelList.push(obj)
        // this.viewer.trackedEntity = modelMan;
        this.handlePolyline(item, modelMan)
    }
    //轨迹线
    handlePolyline(item, modelMan) {
        var pathPosition = new Cesium.SampledPositionProperty();

        this.getPoints(item.points, pathPosition, modelMan)
        var entityPath = this.viewer.entities.add({
            show: true,
            position: pathPosition,
            name: "path",
            path: {
                show: true,
                leadTime: 0,
                trailTime: 60,
                width: 5,
                resolution: 1,
                // material: Cesium.Color.fromCssColorString(item.army),
                // material: new Cesium.PolylineTrailMaterialProperty({ // 尾迹线材质
                //     color: Cesium.Color.RED.withAlpha(0.8)
                // }),
                material: new Cesium.PolylineGlowMaterialProperty({
                    glowPower: 0.3,
                    taperPower: 0.3,
                    // color: Cesium.Color.PALEGOLDENROD,
                    color: Cesium.Color.fromCssColorString('#409EFF')
                }),
            },
        });
        entityPath.originalData = item;
        this.trailEntityList.push(entityPath)
    }
    getPoints(points, pathPosition, modelMan) {
        for (let item of points) {
            let location = item.location;
            let julianDate = Cesium.JulianDate.fromDate(new Date(item.start))
            let position = Cesium.Cartesian3.fromDegrees(location.x, location.y, location.z)
            pathPosition.addSample(julianDate, position)
        }
    }
    callbackPositionProperty(time, item, modelMan, obj) {

        if(item.points.length === 0){

            let model = obj.entity.ref.ref.forms.find(function(form){
                return form.type == 50;
            });
            
            let coord = JSON.parse(model.geom).coordinates;
            let position = Cesium.Cartesian3.fromDegrees(coord[0], coord[1], 0);
            modelMan.currentPos = position
            obj.position = position;
            return position;
        }

        let position;
        let currentTime = this.timeChange2(Cesium.JulianDate.toDate(time))
        let startTime = item.points[0].start;
        let lastTime = item.points[item.points.length - 1].end;
        let lastItem = item.points[item.points.length - 1];
        //设置属性展示
        let popList = Store.getPopList();
        let result = popList.find(popItem => popItem.oid == item.id)

        if (currentTime > lastTime) {
            if (lastItem.location.x && lastItem.location.y) {
                position = Cesium.Cartesian3.fromDegrees(lastItem.location.x, lastItem.location.y, location.z)
            }

        } else if (currentTime < startTime) {

        } else {
            
            for (let pointInfo of item.points) {
                let location = pointInfo.location;
                // let direction = pointInfo.direction - 180;
                let start = pointInfo.start;
                let end = pointInfo.end;

                if (currentTime >= start && currentTime < end) {
                    modelMan.model.show = true
                    // modelMan.orientation = this.setModelDirection(location.x, location.y, direction)
                    let newPosition = this.handleCHA(currentTime, start, end, pointInfo, obj.id)
                    position = Cesium.Cartesian3.fromDegrees(newPosition.x, newPosition.y, newPosition.z)
                    //处理显示弹窗
                    let windowPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, position);
                    if (result) {
                        result.pixel = windowPos;
                    }
                }
            }
        }

        //处理弹窗移动
        if (result) {

            function getCurrentDynamic(tag){

                let attr = item.dynamics.find(item => {
                    return item.name == tag;
                });
    
                let data = attr.data.find(item => {
                    return currentTime >= item.start && currentTime < item.end
                });
                
                return data.value;
            }


            result.attrInfo = {
                temperature: getCurrentDynamic('温度'),
                pressure: getCurrentDynamic('压强'),
                humidity: getCurrentDynamic('湿度'),
                mach: getCurrentDynamic('马赫'),
                gas: getCurrentDynamic('油量'),
                pitch: getCurrentDynamic('俯仰角')
            };

            // 调试用：限制循环输出次数
            /*if(this.global < 10){
                console.log(result.attrInfo);
                this.global++;
            }*/

        } else {

            // modelMan.ellipsoid.show = false
        }

        //更新弹窗
        vm.$emit(SEND.setPopup, {
            data: popList,
        });

        vm.$emit(SEND.tick, {
            time: Cesium.JulianDate.toDate(time)
        });

        Store.getPopList(popList);
        modelMan.currentPos = position
        obj.position = position;
        // //修改所有血液
        // let windowPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, position);
        // this.handleBooldList(item, healthValue, windowPos, modelMan)
        return position
    }
    callbackAttackLineProperty = (time, result, obj) => {
        let posList = [];
        let popList = Store.getPopList();
        return posList
    }
    //补插值
    handleCHA(time, start, end, pointInfo, id, behavior) {
        let x = pointInfo.location.x;
        let y = pointInfo.location.y;
        let z = pointInfo.location.z;
        let tep = end - start;
        let persent = (time - start) / tep;
        x = (pointInfo.endLocation.x - pointInfo.location.x) * persent + pointInfo.location.x;
        y = (pointInfo.endLocation.y - pointInfo.location.y) * persent + pointInfo.location.y;
        return {
            x,
            y,
            z
        }
    }
}

export default CesiumMap;